package com.sbmoon.db;

import java.sql.*;
import java.io.*;
import java.util.*;

import javax.naming.*;
import javax.sql.*;
import javax.naming.*;

import oracle.jdbc.pool.*;

import com.sbmoon.util.*;

public class DatabaseOracle extends Database {

	public String getJndiName() {
		return jndiName;
	}

	public void setJndiName(String jndiName) {
		this.jndiName = jndiName;
	}

	@Override
	protected Connection createConnection_Impl() throws Exception {

		try {
			Connection jndiConn = this.getJndiConnection( this.getJndiName() );

			if( jndiConn != null ) {
				jndiConn.setAutoCommit( this.isAutoCommit() );
			}

			return jndiConn;
		} catch (Exception ex) {
			if( true ) {
				this.debug("Oracle JNDI is wrong !!! Contact WAS Admin, please!!!!");
				return null;
			} else {
				return this.getOracleConnCacheConnection();
			}
		}

	}

	@Override
	public void loadDriver() {

	}

	public OracleDataSource getOracleDataSource() throws Exception {

		String dbUrl = this.getDbUrl();

		if( false ) {
			this.debug("Connecting to " + dbUrl );
		}

		OracleDataSource ods = new OracleDataSource();

		ods.setURL( dbUrl );

		return ods;

	}

	protected Connection getOracleConnCacheConnection() throws Exception {
		OracleDataSource ods = this.getOracleDataSource();
		Connection conn = ods.getConnection();

		this.debug("Oracle connection has been connected!" , false );

		return conn;

	}

	protected Connection getJndiConnection(String jndiName) throws Exception {
		try {
			Context ctx = new InitialContext();
			DataSource ds = (javax.sql.DataSource) ctx.lookup(jndiName);
			Connection conn = ds.getConnection();

			this.debug("JNDI Oracle connection has been connected!");

			return conn;
		} catch (Exception ex) {
			throw ex;
		}
	}

	private DatabaseOracle(String dbUrl) {
		super(dbUrl, getEncodingOracle() );

	}

	public static Encoding getEncodingOracle() {
		return ORACLE_ENCODING;
	}

	private static String getDbUrl_Oracle( String host, String sid, int port, String user, String passwd ) {
		String connect_string = "jdbc:oracle:thin:" + user + "/" + passwd + "@//" + host + ":" + port + "/" + sid;
		return connect_string;
	}

	public static DatabaseOracle getDatabaseOracleFromBundle( String bundleFileName, boolean useCache ) {

		if( false ) {
			return new DatabaseOracle( "");
		}

		ResourceBundle bundle = BundleUtil.getBundle( bundleFileName , useCache );

		String host = bundle.getString( "HOSTNAME" );
		String sid = bundle.getString( "SID" );
		int port = Integer.parseInt( bundle.getString( "PORT" ) );
		String user = bundle.getString( "USERNAME" );
		String passwd = bundle.getString( "PASSWORD" );

		String dbUrl = DatabaseOracle.getDbUrl_Oracle( host, sid, port, user, passwd );

		return getDatabaseOracle( dbUrl );
	}

	private static DatabaseOracle getDatabaseOracle( String dbUrl ) {

		if( true ) {
			return new DatabaseOracle( dbUrl );
		}

		DatabaseOracle oracle = oracleList.get( dbUrl );

		if( oracle == null ) {
			oracle = new DatabaseOracle( dbUrl );
			oracleList.put(dbUrl, oracle);
		}

		return oracle ;
	}

	private static Hashtable< String, DatabaseOracle > oracleList = new Hashtable< String, DatabaseOracle >();

	private static Properties loadParams(String file) throws IOException {
		// Loads a ResourceBundle and creates Properties from it
		Properties prop = new Properties();
		ResourceBundle bundle = ResourceBundle.getBundle(file);
		Enumeration<String> it = bundle.getKeys();
		String key = null;
		Object val;
		while (it.hasMoreElements()) {
			key = it.nextElement();
			val = bundle.getObject(key);

			if( true ) {
				System.out.println( "key:" + key + ", val:" + val );
			}

			prop.put(key,  val );
		}
		return prop;
	}

	private static final Encoding ORACLE_ENCODING = new DirectEncoding( "KO16KSC5601" ) ;
	//private static final Encoding ORACLE_ENCODING = new DirectEncoding( "EUC-KR" ) ;

	// member
	private String jndiName = "oraDB";
	// end of member

}
